home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************
- "scroll.c"
-
- by John A. Love, III [ Washington Apple Pi Users' Group]
-
- using Symantec's "THINK C", v 5.00
- *********************************************************/
-
-
-
- #include "protos"
-
- #include "globals.h"
- #include "extern.h"
-
-
-
-
- /* +++++++++++++++++++++
- ** Our local prototypes:
- ** +++++++++++++++++++++ */
-
- pascal void UpActionProc (ControlHandle ctl, short part);
- pascal void DownActionProc (ControlHandle ctl, short part);
- void ScrollToThumbPosition (ControlHandle ctl);
- void DoPageUp (ControlHandle ctl);
- void DoPageDown (ControlHandle ctl);
- void ScrollContents (ControlHandle ctl, short dh, short dv);
- void SetMaxCtlValue (ControlHandle ctl, short excess);
- void SetCtlValueToMin (ControlHandle ctl);
-
-
-
- /* +++++++++++++++++++++++++++++++++++++++
- ** Our Globals for the scrolling routines:
- ** +++++++++++++++++++++++++++++++++++++++ */
-
- #define kFlashDelay 8
-
- WindowPtr window;
- long VertOrHoriz;
- short oldCtlValue;
- ControlHandle ourControl;
- Rect windContentsRect, fullContentsRect, updateRect;
- long finalTicks;
-
-
-
-
- short GetControlType (ControlHandle ctl) {
-
- short RomMapInsertLoc = 0x0B9E;
- /* short mapTrue = -1; */
-
- short varCode, CDEFRsrcID, cType;
- Handle CDEFHandle;
- ResType CDEFType;
- Str255 CDEFName;
-
-
- varCode = GetCVariant(ctl);
-
- CDEFHandle = (*ctl)->contrlDefProc;
- CDEFHandle = (Handle)QuickStrip((longPtr)CDEFHandle);
- ;
- LoadResource(CDEFHandle); /* May have been purged ... */
- *((wordPtr)RomMapInsertLoc) = mapTrue; /* Thanks, Ben Cranston !! */
- GetResInfo(CDEFHandle, &CDEFRsrcID, &CDEFType, CDEFName);
-
- cType = 16 * CDEFRsrcID + varCode;
- return (cType);
-
- } /* GetControlType */
-
-
-
- ControlHandle GetDefaultButton (DialogPtr dlg) {
-
- short bType;
- Handle bHandle;
- Rect bRect;
-
-
- if (dlg == nil) return (nil);
- ;
- GetDItem(dlg, ((DialogPeek)dlg)->aDefItem, &bType, &bHandle, &bRect);
- if (bType == ctrlItem + btnCtrl) return ( (ControlHandle)bHandle );
- else return (nil);
-
- } /* GetDefaultButton */
-
-
-
- void FrameDefaultButton (DialogPtr dlg) {
- /* See "THINKin' CaP", Winter 1991 */
-
- ControlHandle okButton;
- Rect bRect;
- short bHeight, roundCorner;
- PenState pnState;
- RGBColor foreColor;
- AuxCtlHandle acHndl;
- CCTabHandle ccTable;
-
-
- okButton = GetDefaultButton(dlg);
- if (okButton == nil) return;
-
- GetPenState(&pnState);
- ;
- PenNormal();
- PenSize(3, 3);
-
- bRect = (*okButton)->contrlRect;
- bHeight = bRect.bottom - bRect.top;
-
- InsetRect(&bRect, -4, -4);
- roundCorner = (bHeight + 1) / 2;
- if ( !isActive((*okButton)->contrlOwner) ) PenPat(&gray);
-
- if (gMac2) {
- GetForeColor(&foreColor);
- if (GetAuxCtl(okButton, &acHndl)) {
- ccTable = (**acHndl).acCTable;
- RGBForeColor(& ((**ccTable).ctTable)[cFrameColor].rgb );
- }
- } /* gMac2 */
- ;
- FrameRoundRect(&bRect, roundCorner, roundCorner);
- ;
- if (gMac2) RGBForeColor(&foreColor);
-
- // ValidRect(&bRect); -- causes problems with updates.
- ;
- SetPenState(&pnState);
-
- } /* FrameDefaultButton */
-
-
-
- void SimulateClick (ControlHandle ctl) {
-
-
- HiliteControl(ctl, inButton);
- Delay(kFlashDelay, &finalTicks);
- HiliteControl(ctl, drawCntl);
-
- } /* SimulateClick */
-
-
-
- /* -----------------------------------------------------
- ** Mouse clicked on the line arrows
- **
- ** NOTE As a matter of academic principle, avoid speed
- ** penalities associated with TRAP overhead if possible.
- ** ----------------------------------------------------- */
-
- pascal void UpActionProc (ControlHandle ctl, short part) {
-
- short newCtlValue; /* # of lines */
- short dv, dh, difference; /* # of pixels */
- Rect temp;
-
-
- if (part == 0) return; /* Mouse moved OUTSIDE the Control !! */
-
- oldCtlValue = (**ctl).contrlValue;
- dv = 12; /* Vertical, NOT sideways !! */
- dh = 0;
-
- difference = (oldCtlValue - (**ctl).contrlMin) * 12;
- if (difference == 0) return; /* Prevent flickering. */
- if (difference < dv) dv = difference;
-
- newCtlValue = oldCtlValue - 1; /* Decrement one line's worth. */
- temp = (**ctl).contrlRect; // Just because _SetCtlValue is buggy for
- InsetRect(&temp, 1, 1); // a Mac II set to black-and-white.
- ClipRect(&temp); // Mac II in color works okay, though ?????
- SetCtlValue(ctl, newCtlValue);
- ClipRect(&window->portRect); /* Reset. */
-
- if (VertOrHoriz == horizScrollID)
- {
- dh = dv; /* Sideways, NOT vertical !! */
- dv = 0;
- } /* in horizontal scroll bar */
-
- ScrollContents(ctl, dh, dv); // Contents scroll DOWN, or RIGHT.
-
- Delay(kFlashDelay, &finalTicks); /* ... otherwise too fast. */
-
- } /* UpActionProc */
-
-
-
- pascal void DownActionProc (ControlHandle ctl, short part) {
-
- short newCtlValue; /* # of lines */
- short dv, dh, difference; /* # of pixels */
- Rect temp;
-
-
- if (part == 0) return; /* Mouse moved OUTSIDE the Control !! */
-
- oldCtlValue = (**ctl).contrlValue;
- dv = 12; /* Vertical, NOT sideways !! */
- dh = 0;
-
- difference = ((**ctl).contrlMax - oldCtlValue) * 12;
- if (difference == 0) return; /* Prevent flickering. */
- if (difference < dv) dv = difference;
-
- newCtlValue = oldCtlValue + 1; /* Bump it one line's worth. */
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1);
- ClipRect(&temp);
- SetCtlValue(ctl, newCtlValue);
- ClipRect(&window->portRect); /* Reset. */
-
- if (VertOrHoriz == horizScrollID)
- {
- dh = dv; /* Sideways, NOT vertical !! */
- dv = 0;
- } /* in horizontal scroll bar */
-
- ScrollContents(ctl, -dh, -dv); // Contents scroll UP, or LEFT.
-
- Delay(kFlashDelay, &finalTicks); /* ... otherwise too fast. */
-
- } /* DownActionProc */
-
-
-
- /* -----------------------------------------------------------------
- ** Scroll contents of window to match the pre-set Scroll Bar setting
- ** ----------------------------------------------------------------- */
-
- void ScrollToThumbPosition (ControlHandle ctl) {
-
- short newCtlValue, dh, dv;
-
-
- dh = 0;
- dv = 0;
- newCtlValue = (**ctl).contrlValue;
-
- if (VertOrHoriz == horizScrollID)
- dh = -(newCtlValue - oldCtlValue) * 12; /* Normally, teLineHite */
- else /* = vertScrollID */ dv = -(newCtlValue - oldCtlValue) * 12;
-
- ScrollContents(ctl, dh, dv);
-
- Delay(8, &finalTicks);
-
- } /* ScrollToThumbPosition */
-
-
-
- /* ----------------------------------------------
- ** Thumb goes UP; text, PICTure etc. scrolls DOWN
- ** ---------------------------------------------- */
-
- void DoPageUp (ControlHandle ctl) {
-
- short partControl, newCtlValue, dv, ctlDelta;
- Point newPoint;
- Rect temp;
-
-
- if (VertOrHoriz == horizScrollID)
- /* = (right+1-left) - scrollWidth: */
- dv = window->portRect.right - window->portRect.left - growBoxSize;
- else /* VertOrHoriz = vertScrollID */
- /* = (bottom+1-top) - scrollHeight: */
- dv = window->portRect.bottom - window->portRect.top - growBoxSize;
- ctlDelta = dv;
- /* Normally divide by teLineHite, a field of the TERecord whose Handle */
- /* is usually stored in the wRefCon field of the WindowRecord */
- ctlDelta = (ctlDelta / 12) - 1; /* Leave 1 line's-worth showing. */
-
- while (StillDown()) {
-
- GetMouse(&newPoint);
- partControl = TestControl(ctl, newPoint);
- if (partControl == inPageUp) { /* Still INSIDE Control ... */
-
- oldCtlValue = (**ctl).contrlValue;
- newCtlValue = oldCtlValue - ctlDelta;
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1);
- ClipRect(&temp);
- SetCtlValue(ctl, newCtlValue); /* Compensates if newCtlValue */
- ClipRect(&window->portRect); /* overshoots ctlMin. */
- ScrollToThumbPosition(ctl);
-
- } /* if partControl = inPageUp */
-
- } /* while StillDown */
-
- } /* DoPageUp */
-
-
-
- /* ----------------------------------------------
- ** Thumb goes DOWN; text, PICTure etc. scrolls UP
- ** ---------------------------------------------- */
-
- void DoPageDown (ControlHandle ctl) {
-
- short partControl, newCtlValue, dv, ctlDelta;
- Point newPoint;
- Rect temp;
-
-
- if (VertOrHoriz == horizScrollID)
- /* = (right+1-left) - scrollWidth: */
- dv = window->portRect.right - window->portRect.left - growBoxSize;
- else /* VertOrHoriz = vertScrollID */
- /* = (bottom+1-top) - scrollHeight: */
- dv = window->portRect.bottom - window->portRect.top - growBoxSize;
-
- ctlDelta = (dv / 12) - 1;
-
- while (StillDown()) {
-
- GetMouse(&newPoint);
- partControl = TestControl(ctl, newPoint);
- if (partControl == inPageDown) { /* Still INSIDE Control ... */
-
- oldCtlValue = (**ctl).contrlValue;
- newCtlValue = oldCtlValue + ctlDelta;
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1);
- ClipRect(&temp);
- SetCtlValue(ctl, newCtlValue); /* Compensates if newCtlValue */
- ClipRect(&window->portRect); /* overshoots ctlMax. */
- ScrollToThumbPosition(ctl);
-
- } /* if partControl = inPageDown */
-
- } /* while StillDown */
-
- } /* DoPageDown */
-
-
-
- void ScrollContents(ControlHandle ctl, short dh, short dv) {
-
-
-
- } /* ScrollContents */
-
-
-
- /* --------------------------
- ** Our main Scrolling routine
- ** -------------------------- */
-
- void Scroll (ControlHandle ctl, short part, Point Pt) {
-
-
- window = (**ctl).contrlOwner;
- SetPort(window);
- VertOrHoriz = (**ctl).contrlRfCon; /* Up/Down or sideways ?? */
- oldCtlValue = GetCtlValue(ctl);
-
- switch (part) {
-
- case inUpButton:
- /* Throw away the result: */
- TrackControl(ctl, Pt, (ProcPtr)&UpActionProc);
- break;
-
- case inDownButton:
- TrackControl(ctl, Pt, (ProcPtr)&DownActionProc);
- break;
-
- case inPageUp:
- DoPageUp(ctl);
- break;
-
- case inPageDown:
- DoPageDown(ctl);
- break;
-
- case inThumb:
- {
- Rect temp;
-
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1);
- ClipRect(&temp);
- if (TrackControl(ctl, Pt, nil) != 0)
- ScrollToThumbPosition(ctl);
- ClipRect(&window->portRect); /* Reset. */
- break;
- }
-
- default: break;
-
- } /* switch */
-
- } /* Scroll */
-
-
-
- /* -------------------------------------------------------
- ** Set ONLY the maximum value(s) because the attached CNTL
- ** resources(s) specify the minimum -- generally zero.
- ** ------------------------------------------------------- */
-
- void SetMaxCtlValue (ControlHandle ctl, short excess) {
-
- short maxValue;
- Rect temp;
-
-
- if (excess <= 0)
- maxValue = (**ctl).contrlMin; /* Inactivates Control since max = min. */
- else // Contents taller than window->
- maxValue = (excess + 11) / 12; /* ... by this much [rounded up]. */
-
- if (maxValue != (**ctl).contrlMax)
- {
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1);
- ClipRect(&temp);
- SetCtlMax(ctl, maxValue);
- }
-
- } /* SetMaxCtlValue */
-
-
-
- void SetMaxCtls (WindowPtr windPtr) {
-
- RgnHandle oldClip;
- ControlHandle ctlHndl;
- short dest, view;
-
-
- oldClip = NewRgn();
- GetClip(oldClip);
-
- ctlHndl = ScrollVert(windPtr);
- if (ctlHndl != nil)
- {
- view = windContentsRect.bottom - windContentsRect.top;
- dest = fullContentsRect.bottom - fullContentsRect.top;
- SetMaxCtlValue(ctlHndl, dest - view);
- } /* if ctlHndl != nil */
-
- /* ----- */
-
- ctlHndl = ScrollHoriz(windPtr);
- if (ctlHndl != nil)
- {
- view = windContentsRect.right - windContentsRect.left;
- dest = fullContentsRect.right - fullContentsRect.left;
- SetMaxCtlValue(ctlHndl, dest - view);
- } /* if ctlHndl != nil */
-
- SetClip(oldClip);
- DisposeRgn(oldClip);
-
- } /* SetMaxCtls */
-
-
-
- /* --------------------------------
- ** Called by the "HandleMouse" PROC
- ** -------------------------------- */
-
- void SetCtlValueToMin (ControlHandle ctl) {
-
- Rect temp;
-
-
- if (ctl == nil) return;
-
- temp = (**ctl).contrlRect;
- InsetRect(&temp, 1, 1); /* See comments in "UpActionProc". */
- ClipRect(&temp);
- SetCtlValue(ctl, GetCtlMin(ctl));
-
- } /* SetCtlValueToMin */
-
-
-
- void SetCtlsToMin (WindowPtr windPtr) {
-
- RgnHandle oldClip;
-
-
- oldClip = NewRgn();
- GetClip(oldClip);
-
- SetCtlValueToMin(ScrollHoriz(windPtr));
- SetCtlValueToMin(ScrollVert(windPtr));
-
- SetClip(oldClip);
- DisposeRgn(oldClip);
-
- } /* SetCtlsToMin */
-
-
-
- /* --------------------------
- ** Does she or doesn't she ??
- ** -------------------------- */
-
- Boolean DrawMyControl (ControlHandle ctl) {
-
- if ( (ctl != nil) && ((**ctl).contrlMax > (**ctl).contrlMin) ) return (true);
- else return (false);
-
- } /* DrawMyControl */
-
-
-
- /* --------------------------------
- Retrieve Control Handle, if any:
- -------------------------------- */
-
- ControlHandle ScrollHoriz (WindowPtr wp) {
-
- ourControl = ((WindowPeek)wp)->controlList;
-
- while (ourControl) {
- if ((*ourControl)->contrlRfCon == horizScrollID) break;
- ourControl = (*ourControl)->nextControl;
- } /* while */
-
- return(ourControl);
-
- } /* ScrollHoriz */
-
-
-
- ControlHandle ScrollVert (WindowPtr wp) {
-
- ourControl = ((WindowPeek)wp)->controlList;
-
- while (ourControl) {
- if ((*ourControl)->contrlRfCon == vertScrollID) break;
- ourControl = (*ourControl)->nextControl;
- } /* while */
-
- return(ourControl);
-
- } /* ScrollVert */
-
-
-
- /* ------------------
- Hello, or GoodBye:
- ------------------ */
-
- void ScrollShow (WindowPtr wp) {
-
- ourControl = ScrollVert(wp);
- ;
- if (ourControl) ShowControl(ourControl);
- /* ----- */
- ourControl = ScrollHoriz(wp);
- ;
- if (ourControl) ShowControl(ourControl);
-
- } /* ScrollShow */
-
-
-
- void ScrollHide (WindowPtr wp) {
-
- ourControl = ScrollVert(wp);
- ;
- if (ourControl) HideControl(ourControl);
- /* ----- */
- ourControl = ScrollHoriz(wp);
- ;
- if (ourControl) HideControl(ourControl);
-
- } /* ScrollHide */
-
-
-
- /* -----------------------------------------------------------------
- Explicitly include the Scroll Bars in the window's Update region.
- This Update region will purposely overlap the Grow Box.
- ----------------------------------------------------------------- */
-
- void InvalidScroll (WindowPtr wp) {
-
- if (ScrollVert(wp))
- {
- updateRect = wp->portRect;
- updateRect.left = updateRect.right + frame - scrollWidth;
- InvalRect(&updateRect);
- } /* if a vertical Scroll Bar */
-
- if (ScrollHoriz(wp))
- {
- updateRect = wp->portRect;
- updateRect.top = updateRect.bottom + frame - scrollHeight;
- InvalRect(&updateRect);
- } /* if */
-
- } /* InvalidScroll */
-
-
-
- void ValidScroll (WindowPtr wp) {
-
- if (ScrollVert(wp))
- {
- updateRect = wp->portRect;
- updateRect.left = updateRect.right + frame - scrollWidth;
- ValidRect(&updateRect);
- } /* if a vertical Scroll Bar */
-
- if (ScrollHoriz(wp))
- {
- updateRect = wp->portRect;
- updateRect.top = updateRect.bottom + frame - scrollHeight;
- ValidRect(&updateRect);
- } /* if */
-
- } /* ValidScroll */
-
-
-
- void ScrollResize (WindowPtr wp) {
- /* Remember, the portRect does NOT include the window frame,
- whereas the Scroll Bar and Grow Box sizes do: */
-
- Rect contentRect;
- short ctlWidth, ctlHeight;
- short ctlTop, ctlLeft, ctlBottom, ctlRight;
-
-
- contentRect = wp->portRect;
-
- /* Need to clip to new portRect for growing or zooming because window
- is still clipped to OLD portRect. Otherwise, upon enlarging the
- window, the ScrollShow PROC would NOT display the Scroll Bars: */
-
- ClipRect(&contentRect);
-
- ScrollHide(wp); /* Hide-and-Go Seek !! */
-
- ourControl = ScrollVert(wp);
- if (ourControl)
- {
- ctlTop = contentRect.top - frame;
- ctlLeft = (contentRect.right + frame) - scrollWidth;
- ctlBottom = (contentRect.bottom + frame) - growBoxSize;
- ctlHeight = ctlBottom - ctlTop;
- ;
- SizeControl(ourControl, scrollWidth, ctlHeight);
- MoveControl(ourControl, ctlLeft, ctlTop);
- } /* Vertical ScrollBar */
- /* ----- */
- ourControl = ScrollHoriz(wp);
- if (ourControl)
- {
- ctlTop = (contentRect.bottom + frame) - scrollHeight;
- ctlLeft = contentRect.left - frame;
- ctlRight = (contentRect.right + frame) - growBoxSize;
- ctlWidth = ctlRight - ctlLeft;
- ;
- SizeControl(ourControl, ctlWidth, scrollHeight);
- MoveControl(ourControl, ctlLeft, ctlTop);
- } /* Horizontal ScrollBar */
-
- ScrollShow(wp); /* Peek-a-Boo !! */
-
- } /* ScrollResize */
-
-
-
- /* --------------------------------------------
- Scrolls your text string from right to left.
- -------------------------------------------- */
-
- void ScrollText (Str255 myText, Rect *box) {
-
- register short textLen;
- unsigned char textBuf[256];
- register short boxWidth;
- Boolean leftJustify;
- register short widthSpace, x0, y0;
- register short bufWidth;
- register short firstChar, lastChar, charCount;
- long finalTicks;
- unsigned char SP = ' ';
-
-
- if ( !isPString((char*)myText) ) CtoPstr((char*)myText);
-
- textLen = *myText;
- if (textLen == 0) return; /* Null string. */
-
- textLen++; /* Include the length byte. */
- BlockMove(myText, textBuf, sizeof(textLen));
- textBuf[0] = textLen; /* = textLen+1 from above. */
- textBuf[textLen] = SP; /* Add a trailing space. */
-
- widthSpace = CharWidth(SP);
- boxWidth = box->right - box->left;
- if (boxWidth <= widthSpace) return;
- y0 = box->bottom - box->top;
- if (y0 < 10) return; /* NOT tall enough !! */
- y0 = (y0 - 6) / 2;
- y0 = box->bottom - y0; /* y0 = bottom-7 for box.tall = 20 */
-
- firstChar = 1; /* Start AFTER length byte. */
- lastChar = 1;
- charCount = 1;
- leftJustify = FALSE; /* Assume right-justified. */
-
- /* Shake, Rattle & Scroll, Baby !!! */
-
- while (1)
- {
- bufWidth = TextWidth(textBuf, firstChar, charCount);
- while (bufWidth > boxWidth)
- {
- bufWidth = TextWidth(textBuf, firstChar, charCount);
- firstChar++; /* Drop first character and */
- charCount--; /* try for fit again. */
- } /* while (bufWidth > boxWidth) */
-
- /* it Fits */
- itFits:
- EraseRect(box);
- x0 = box->right - bufWidth;
- if (x0 <= box->left) leftJustify = TRUE; /* Needed ONLY for very */
- /* short strings. */
- if (leftJustify) x0 = box->left;
- /* y0 = box->bottom - 7; */
- MoveTo(x0, y0);
- DrawText(textBuf, firstChar, charCount);
- lastChar++;
-
- if (lastChar > textLen) /* We've reached the end. */
- {
- if (!leftJustify) {
- /* short string NOT to left edge yet. */
- bufWidth += widthSpace;
- Delay(10, &finalTicks); /* ... otherwise too quick. */
- goto itFits;
- }
- else { /* At left edge. */
- firstChar++;
- charCount--;
- if (charCount == 0) break; /* All characters moved left. */
- }
- }
- else charCount++; /* Next character. */
-
- scrollAgain:
- Delay(10, &finalTicks); /* ... otherwise too quick. */
- } /* while (1) */
-
- outtahere: /* Fini!! */
- ValidRect(box); /* No Updates, please ... */
-
- } /* ScrollText */
-
-
-
-
- /* { end file = "scroll.c" } */
-